use rocket::Route;

use std::path::{PathBuf, Path};
use rocket::fs::{NamedFile, relative, TempFile};
use rocket::response::Redirect;
use rocket::serde::{json::Value, json::json};
use rocket::form::{Form, FromForm};

pub fn all() -> Vec<Route> {
  routes![favico, index, static_file, redirect, upload_raw, upload_form]
}

#[derive(FromForm)]
pub struct Upload<'r> {
    file: TempFile<'r>,
    path: String
}

#[get("/")]
pub fn index() -> &'static str {
    "Welcome to Rocket web-server!"
}

#[get("/app/<_..>/index")] // ADD "/app/" to avoid conflict with "/static/<path..>"
pub fn redirect() -> Redirect {
    Redirect::to(uri!(index))
}

#[get("/favicon.ico")]
pub async fn favico() -> Option<NamedFile> {
    let path = Path::new("favicon.ico");
    NamedFile::open(path).await.ok()
}

#[get("/static/<path..>")]
pub async fn static_file(path: PathBuf) -> Option<NamedFile> {
    let path = Path::new(relative!("static")).join(path);
    NamedFile::open(path).await.ok()
}

#[post("/upload1", data = "<data>")]
pub async fn upload_form(mut data: Form<Upload<'_>>) -> Value {
    let save_path = Path::new(relative!("static")).join(data.path.clone());
    std::fs::create_dir_all(save_path.parent().unwrap()).unwrap();
    match data.file.persist_to(save_path).await {
        Ok(_) => json!({ "msg": "success", "status": 0 }),
        Err(e) => {
            println!("{}", e);
            json!({ "msg": "fail", "status": 1 })
        }
    }
}

#[post("/upload2/<path..>", data = "<file>")]
pub async fn upload_raw(path: PathBuf, mut file: TempFile<'_>) -> Value {
    let save_path = Path::new(relative!("static")).join(path);
    std::fs::create_dir_all(save_path.parent().unwrap()).unwrap();
    match file.persist_to(save_path).await {
        Ok(_) => json!({ "msg": "success", "status": 0 }),
        Err(e) => {
            println!("{}", e);
            json!({ "msg": "fail", "status": 1 })
        }
    }
}
